/**
 * 性能优化工具类
 */
export class PerformanceHelper {
  /**
   * 防抖函数
   * @param func 要防抖的函数
   * @param wait 等待时间
   * @param immediate 是否立即执行
   */
  static debounce<T extends (...args: any[]) => any>(
    func: T,
    wait: number,
    immediate: boolean = false
  ): (...args: Parameters<T>) => void {
    let timeout: number | null = null;
    
    return function executedFunction(...args: Parameters<T>) {
      const later = () => {
        timeout = null;
        if (!immediate) func(...args);
      };
      
      const callNow = immediate && !timeout;
      
      if (timeout) clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      
      if (callNow) func(...args);
    };
  }

  /**
   * 节流函数
   * @param func 要节流的函数
   * @param limit 限制时间
   */
  static throttle<T extends (...args: any[]) => any>(
    func: T,
    limit: number
  ): (...args: Parameters<T>) => void {
    let inThrottle: boolean;
    
    return function executedFunction(...args: Parameters<T>) {
      if (!inThrottle) {
        func(...args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    };
  }

  /**
   * 浅克隆对象
   * @param obj 要克隆的对象
   */
  static shallowClone<T>(obj: T): T {
    if (obj === null || typeof obj !== 'object') return obj;
    if (Array.isArray(obj)) return [...obj] as T;
    return { ...obj };
  }

  /**
   * 安全的深度克隆（性能优化版）
   * @param obj 要克隆的对象
   * @param maxDepth 最大深度
   */
  static safeDeepClone<T>(obj: T, maxDepth: number = 3): T {
    if (obj === null || typeof obj !== 'object') return obj;
    if (maxDepth <= 0) return obj;
    
    if (Array.isArray(obj)) {
      return obj.map(item => this.safeDeepClone(item, maxDepth - 1)) as T;
    }
    
    const cloned: any = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        cloned[key] = this.safeDeepClone(obj[key], maxDepth - 1);
      }
    }
    return cloned;
  }

  /**
   * 缓存函数结果
   * @param func 要缓存的函数
   * @param keyGenerator 键生成器
   */
  static memoize<T extends (...args: any[]) => any>(
    func: T,
    keyGenerator?: (...args: Parameters<T>) => string
  ): T {
    const cache = new Map<string, ReturnType<T>>();
    
    return ((...args: Parameters<T>): ReturnType<T> => {
      const key = keyGenerator 
        ? keyGenerator(...args) 
        : JSON.stringify(args);
      
      if (cache.has(key)) {
        return cache.get(key)!;
      }
      
      const result = func(...args);
      cache.set(key, result);
      return result;
    }) as T;
  }

  /**
   * 异步防抖
   * @param func 异步函数
   * @param wait 等待时间
   */
  static asyncDebounce<T extends (...args: any[]) => Promise<any>>(
    func: T,
    wait: number
  ): (...args: Parameters<T>) => Promise<ReturnType<T>> {
    let timeout: number | null = null;
    let lastPromise: Promise<ReturnType<T>> | null = null;
    
    return function executedFunction(...args: Parameters<T>): Promise<ReturnType<T>> {
      return new Promise((resolve, reject) => {
        if (timeout) {
          clearTimeout(timeout);
        }
        
        timeout = setTimeout(async () => {
          try {
            const result = await func(...args);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        }, wait);
      });
    };
  }

  /**
   * 批量处理
   * @param items 要处理的项
   * @param processor 处理器函数
   * @param batchSize 批次大小
   */
  static async batchProcess<T, R>(
    items: T[],
    processor: (item: T) => Promise<R>,
    batchSize: number = 10
  ): Promise<R[]> {
    const results: R[] = [];
    
    for (let i = 0; i < items.length; i += batchSize) {
      const batch = items.slice(i, i + batchSize);
      const batchResults = await Promise.all(batch.map(processor));
      results.push(...batchResults);
    }
    
    return results;
  }

  /**
   * 延迟执行
   * @param func 要执行的函数
   * @param delay 延迟时间
   */
  static delay<T extends (...args: any[]) => any>(
    func: T,
    delay: number
  ): (...args: Parameters<T>) => Promise<ReturnType<T>> {
    return (...args: Parameters<T>): Promise<ReturnType<T>> => {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(func(...args));
        }, delay);
      });
    };
  }
}

/**
 * 简化的性能优化函数
 */
export const debounce = <T extends (...args: any[]) => any>(
  func: T, 
  wait: number, 
  immediate?: boolean
) => PerformanceHelper.debounce(func, wait, immediate);

export const throttle = <T extends (...args: any[]) => any>(
  func: T, 
  limit: number
) => PerformanceHelper.throttle(func, limit);

export const shallowClone = <T>(obj: T) => PerformanceHelper.shallowClone(obj);

export const safeDeepClone = <T>(obj: T, maxDepth?: number) => 
  PerformanceHelper.safeDeepClone(obj, maxDepth);

export const memoize = <T extends (...args: any[]) => any>(
  func: T, 
  keyGenerator?: (...args: Parameters<T>) => string
) => PerformanceHelper.memoize(func, keyGenerator);

export const asyncDebounce = <T extends (...args: any[]) => Promise<any>>(
  func: T, 
  wait: number
) => PerformanceHelper.asyncDebounce(func, wait);

export const batchProcess = <T, R>(
  items: T[], 
  processor: (item: T) => Promise<R>, 
  batchSize?: number
) => PerformanceHelper.batchProcess(items, processor, batchSize);

export const delay = <T extends (...args: any[]) => any>(
  func: T, 
  delay: number
) => PerformanceHelper.delay(func, delay);
